package com.qire.manhua.view.comicReader.renderer;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.util.TypedValue;

import com.qire.common.utils.EquipmentInfoUtil;

import java.util.Random;

/**
 * 弹幕
 * Created by summer_xx on 2018/4/20.
 */
public class BulletScreen {

    /**文本大小*/
    public final RectF textRect = new RectF();
    /**视口大小*/
    public final RectF viewport = new RectF();

    private PictureResource pictureResource;
    private Point location;

    private String content = "";
    private int fontSize = 18;
    private int fontColor = Color.WHITE;
    private int shadowColor = Color.WHITE;

    private int showCount = 0;
    private long showStartTime;
    private long pauseDurationTime = 0;
    private long durationTime = -1;
    private boolean isPause = false;

    private Paint paint       = new Paint(Paint.ANTI_ALIAS_FLAG);
    private Paint strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private float padding = 0f;

    private int stepDistance = 5;
    private int moveDistance = 0;
    private int startPoint   = 0;

    public Point getLocation() {
        return location;
    }

    public PictureResource getPictureResource() {
        return pictureResource;
    }

    public String getContent() {
        return content;
    }
    public int getFontColor() {
        return fontColor;
    }
    public int getFontSize() {
        return fontSize;
    }

    public BulletScreen(PictureResource pictureResource, Point location, String content, int fontColor, int shadowColor, int fontSize) {
        if(pictureResource == null) throw new NullPointerException("pictureResource 不能为null");
        this.pictureResource = pictureResource;
        this.location        = location;
        this.content         = content;
        this.fontColor       = fontColor;
        this.shadowColor     = shadowColor;
        this.fontSize        = fontSize;
        init();
    }

    private void init() {

        initPaint();
    	measure();

        Rect pictureViewport = pictureResource.calcViewportRect();

        int distance = (int) (pictureViewport.width() + viewport.width());
        startPoint = pictureViewport.width();
        stepDistance = content.length() / 2;
        stepDistance = Math.max(4, stepDistance);
        stepDistance = Math.min(7, stepDistance);

        durationTime = (distance / stepDistance) * 17;
//        durationTime = (int)(moveDistance/stepDistance) * 20;
    }

    private void initPaint(){

        DisplayMetrics displayMetrics = EquipmentInfoUtil.getDisplayMetrics();//pictureResource.context.getResources().getDisplayMetrics();
        padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5.0f, displayMetrics);

        float textSize    = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, fontSize, displayMetrics);
//        shadowColor = calculateShadow(fontColor);//

        paint.setTextSize(textSize);
        paint.setTypeface(Typeface.DEFAULT_BOLD);
        paint.setColor(fontColor);
        paint.setShadowLayer(10, 0, 0, shadowColor);

        // 复制原来TextView画笔中的一些参数
        strokePaint.setTextSize(textSize);
        strokePaint.setTypeface(Typeface.DEFAULT_BOLD);
    //        strokePaint.setFlags(paint.getFlags());
    //        strokePaint.setAlpha(paint.getAlpha());

        // 自定义描边效果
        strokePaint.setStyle(Paint.Style.STROKE);
        strokePaint.setColor(shadowColor);
        strokePaint.setStrokeWidth(3);
    }

    /**
     * 在RGB模式下,像素亮度的计算公式为:L=R*0.30+G*0.59+B*0.11,简称305911公式(只表示RGB颜色模式中的亮度,也就是直方图中的亮度).
     * 制作过程采用通道混合器(红色:+30%,绿色:+59%,蓝色:+11%;勾选单色)*/
    private int calculateShadow(int fontColor){
        int R = Color.red(fontColor);        //(color >> 16) & 0xFF
        int G = Color.green(fontColor);        //(color >> 8) & 0xFF;
        int B = Color.blue(fontColor);        //color & 0xFF
//        return (255 - (int)(B * 0.11D + G * 0.59D + R * 0.3D))* (16777216);
        return (int) (B * 0.11D + G * 0.59D + R * 0.3D) * (16777216);
    }

    private int getRandom(int min, int max) {
        return new Random().nextInt(max) % (max - min + 1) + min;
    }

    private void measure() {

        Paint.FontMetrics fontMetrics = this.paint.getFontMetrics();
        float textHeight = fontMetrics.descent - fontMetrics.ascent - fontMetrics.leading;
        float textWidth = this.paint.measureText(content);
        textRect.set(0, 0, textWidth, textHeight);

        viewport.set(textRect);
        viewport.inset(-padding, -padding);

    }

    public void draw(Canvas canvas) {
        if(!isPause) {
            moveDistance += stepDistance;
        }
        int move = startPoint - moveDistance;
        canvas.drawText(content, move,(int)(viewport.bottom - padding - paint.descent()), strokePaint);  //描边：左下角点为x,y
        canvas.drawText(content, move,(int)(viewport.bottom - padding - paint.descent()), paint);        //字体：左下角点为x,y

//        System.out.println("BulletScreen === "+content+"   move:"+move +"   moveDistance:" + moveDistance +"  d:" + stepDistance);
//        Rect viewportRect = pictureResource.getViewportRect();
//        System.out.println("BulletScreen === "+showCount+"  t:"+content+"   viewport.bottom:"+viewport.bottom
//                +" location:"+location.y +" viewportRect:"+viewportRect.top+"  "+viewportRect.height());//日志过滤：viewport.bottom:1266.0576
    }

    public void reset(){
        //TODO:新需求要修永久显示并且朝屏幕后拉回来重新显示
        showCount = 0;
    }

    public boolean existIn(Rect screenArea) {
        Rect viewportRect = pictureResource.calcViewportRect();
        if(viewportRect == null)
            return false;
        int x = viewportRect.left + location.x;
        int y = viewportRect.top + location.y;
        return screenArea.contains(x, y);
    }

    public boolean needCorrectionLocation(BulletScreen bulletScreen) {
        boolean needCorrection = false;
        Point correctionLocation = new Point(0, 0);
        Rect viewportRect = pictureResource.calcViewportRect();

        if(viewportRect != null) {
            correctionLocation.offset(viewportRect.left, viewportRect.top);
        }
        correctionLocation.offset(location.x, location.y);

        //屏幕滚动式弹幕初始化离屏位置
        //+50 的偏移为了4舍5入
        viewport.offsetTo(viewportRect.width(),(correctionLocation.y + 50) / 100 * 100);

        if(bulletScreen==null) {
            return needCorrection;
        }

        needCorrection = checkOverlaps(bulletScreen);
        if(needCorrection) {

        }

        return needCorrection;
    }

    private boolean checkOverlaps(BulletScreen bulletScreen) {
        return viewport.top <= bulletScreen.viewport.bottom
                && bulletScreen.viewport.top <= viewport.bottom;
    }

    public boolean isHaveShow() {
        return showCount>0;
    }

    public int getShowCount() {
        return showCount;
    }

    /**已运行时间*/
    public long getElapsedTime() {
        return SystemClock.uptimeMillis() - (showStartTime + pauseDurationTime);
    }

    public boolean isTimeout() {
        if(durationTime==-1 || this.isPause)
            return false;
        return getElapsedTime() > durationTime;
    }

    private long pauseStartTime = -1;
    public void playState(boolean isPause) {
        if(this.isPause == isPause)
            return;
        if(isPause) {
            if(pauseStartTime == -1)
                pauseStartTime = SystemClock.uptimeMillis();
        } else {
            if(pauseStartTime>0){
                long newTime = SystemClock.uptimeMillis();
                this.pauseDurationTime += (newTime - pauseStartTime);
                this.pauseDurationTime = this.pauseDurationTime/16 *16;
            }
            pauseStartTime = -1;
        }
        this.isPause = isPause;
    }

    public BulletScreen getShow() {
        moveDistance = 0;
        pauseDurationTime = 0;
        showStartTime = SystemClock.uptimeMillis();
        showCount++;
        return this;
    }

    public long getShowStartTime() {
		return showStartTime;
    }

}
